home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1991 …esperately Seeking Seven / Desperately Seeking Seven.2mg / Dev.CD.8 / Essentials / Tools / DTS.Samples / SC13Math / Math.asm < prev    next >
Encoding:
Assembly Source File  |  1990-05-25  |  47.0 KB  |  1,376 lines  |  [04] ASCII Text (0x0000)

  1. *******************************************************************************
  2. *
  3. * Math -- Version 3.0
  4. *
  5. * (C)  Copyright Apple Computer, Inc. 1988-1990
  6. * All rights reserved.
  7. *
  8. * Developer Technical Support Apple II Sample Code
  9. *
  10. * by Jim Mensch
  11. *
  12. * Sample to show how to use the Integer math and SANE tools. This program shows
  13. * 2 basic operations performed both with the integer math tools and SANE. The
  14. * first is the calculation and display of a simple SINE curve. The second is
  15. * a more complex Fast Fourier Transform.
  16. *
  17. *******************************************************************************
  18.                     eject
  19.                     
  20. **********************************************************************
  21. *                                                                    *
  22. *             Apple IIGS Source Code Sampler, Volume I               *
  23. *                                                                    *
  24. *             Copyright (c) Apple Computer, Inc. 1988-1990           *
  25. *                       All Rights Reserved                          *
  26. *                                                                    *
  27. *            Written by Apple II Developer Tech Support              *
  28. *                                                                    *
  29. *                                                                    *
  30. *                                                                    *
  31. *  ----------------------------------------------------------------  *
  32. *                                                                    *
  33. *     This program and its derivatives are licensed only for         *
  34. *     use on Apple computers.                                        *
  35. *                                                                    *
  36. *     Works based on this program must contain and                   *
  37. *     conspicuously display this notice.                             *
  38. *                                                                    *
  39. *     This software is provided for your evaluation and to           *
  40. *     assist you in developing software for the Apple IIGS           *
  41. *     computer.                                                      *
  42. *                                                                    *
  43. *     DISCLAIMER OF WARRANTY                                         *
  44. *                                                                    *
  45. *     THE SOFTWARE IS PROVIDED "AS IS" WITHOUT                       *
  46. *     WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,               *
  47. *     WITH RESPECT TO ITS MERCHANTABILITY OR ITS FITNESS             *
  48. *     FOR ANY PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO             *
  49. *     THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH            *
  50. *     YOU.  SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU (AND            *
  51. *     NOT APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE)               *
  52. *     ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING,             *
  53. *     REPAIR OR CORRECTION.                                          *
  54. *                                                                    *
  55. *     Apple does not warrant that the functions                      *
  56. *     contained in the Software will meet your requirements          *
  57. *     or that the operation of the Software will be                  *
  58. *     uninterrupted or error free or that defects in the             *
  59. *     Software will be corrected.                                    *
  60. *                                                                    *
  61. *     SOME STATES DO NOT ALLOW THE EXCLUSION                         *
  62. *     OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY              *
  63. *     NOT APPLY TO YOU.  THIS WARRANTY GIVES YOU SPECIFIC            *
  64. *     LEGAL RIGHTS AND YOU MAY ALSO HAVE OTHER RIGHTS                *
  65. *     WHICH VARY FROM STATE TO STATE.                                *
  66. *                                                                    *
  67. *                                                                    *
  68. **********************************************************************
  69.                     eject
  70.                     
  71.                     case   on
  72.  
  73.                     copy 2/ainclude/E16.Quickdraw
  74.                     copy 2/ainclude/E16.Memory
  75.                     copy 2/ainclude/E16.Window
  76.                     copy 2/ainclude/E16.Dialog
  77.                     copy 2/ainclude/E16.SANE
  78.                     mcopy macros/math.mac1
  79.  
  80. DPHandle            gequ 0
  81. DPPointer           gequ DPHandle+4
  82. DeRef               gequ DPPointer+4
  83.  
  84. ScreenWidth         gequ 640
  85. ScreenMode          gequ $80
  86.  
  87.                     EJECT
  88. *******************************************************************************
  89. *
  90. Math                start
  91. *
  92. * Description:      This main routine calls the other major routines in the 
  93. *                   correct order.
  94. *
  95. *
  96. * Inputs:           None
  97. *
  98. * Outputs:          None
  99. *
  100. * External Refs:
  101. *                   Import QuitParms
  102. *                   Import InitTools
  103. *                   Import InitApp
  104. *                   Import EventLoop
  105. *                   Import CloseTools
  106. *                   Import CloseApp
  107. *
  108. * Entry Points:     None
  109. *
  110. *******************************************************************************
  111.  
  112.                     jsr InitTools
  113.                     jsr InitApp
  114.  
  115.                     _ShowCursor
  116.  
  117.                     jsr EventLoop
  118.                     jsr CloseApp
  119.                     jsr CloseTools
  120.  
  121.                     _Quit QuitParms
  122.  
  123.                     end
  124.  
  125.                     EJECT
  126. *******************************************************************************
  127. *
  128. Globals             data
  129. *
  130. * Description:      Global data for use in all routines of this demo. This area
  131. *                   also contains the data used by StandardLib.aii              
  132. *
  133. *
  134. * Inputs:           None
  135. *
  136. * Outputs:          None
  137. *
  138. * External Refs:
  139. *                   Import displayCache
  140. *
  141. * Entry Points:
  142. *                   Export QuitParms    ; used by Main
  143. *
  144. *******************************************************************************
  145. *
  146. * Standard global data
  147. *
  148. *******************************************************************************
  149.  
  150. TitleString         str 'Apple IIgs Integer Math/Sane demo'
  151. AutString           str 'By Jim Mensch Apple DTS -- Version: 3.0'
  152. VersString          str 'Copyright (c) 1988-1990 Apple Computer'
  153.  
  154.  
  155. MenuHeight          ds 2                ; Stored height of menu bar
  156. MyID                ds 2                ; Application ID
  157. MyDP                ds 2                ; My direct page storage
  158.  
  159. QuitFlag            ds 2
  160. QuitParms           dc i4'0'            ; Pathname of next app
  161.                     dc i2'$00'          ; flags
  162.  
  163. EventRecord         ANOP
  164. EventWhat           ds 2
  165. EventMessage        ds 4
  166. EventWhen           ds 4
  167. EventWhere          ds 4
  168. EventModifiers      ds 2
  169. TaskData            ds 4
  170. TaskMask            dc i4'$0000FFFF'
  171.  
  172. portCacheInfo       ds 4
  173.                     ds 4
  174.                     ds 4
  175.                     ds 4
  176.                     dc i2'$C000'
  177.                     dc i2'0,0,175,599'
  178.                     dc i2'0,0,175,599'
  179.  
  180.                     EJECT
  181. *******************************************************************************
  182. *
  183. * Application specific global data
  184. *
  185. *******************************************************************************
  186.  
  187. ; This is a list of pointers to the text that is used to create our menus. It
  188. ; is used by InitApp to find all of the menu templates and use them to create
  189. ; our menubar. This loop loads MenuPtrLen-4 into an index, gets the
  190. ; corresponding menu template pointer in this table, and uses that in a
  191. ; NewMenu call. It then decrements the index by 4, and repeats the procees
  192. ; until the index is negative.
  193.  
  194. MenuPtr             dc i4'AppMenu'
  195.                     dc i4'FileMenu'
  196. MenuPtrLen          equ *-MenuPtr
  197.  
  198.  
  199. ; Menu list: menu items should be numbered consecutivly starting from 250.
  200. ; As a convention, use 256 as about and 257 as Quit.
  201.  
  202.  
  203.  
  204. AppMenu             dc c'$$@\XN1',i1'$0D'
  205.                     dc c'--About Math...\N256V',i1'$00'
  206.                     dc c'.'
  207. FileMenu            dc c'$$ File \N2',i1'$0D'
  208.                     dc c'--SANE Fast Fourier transform\N260',i1'$00'
  209.                     dc c'--Integer Fast Fourier transform\N261',i1'0'
  210.                     dc c'--Integer Sine wave\N258*Ii',i1'$00'
  211.                     dc c'--SANE Sine wave\N259*SsV',i1'$00'
  212.                     dc c'--Quit\N257*Qq',i1'$00'
  213.                     dc c'.'
  214.  
  215. ; Paramater block used to create the main window for display. All the
  216. ; graphing routines will use this window to draw into.
  217.  
  218. MyWindow            dc i2'WindEnd-*'    ; size of paramBlock
  219.                     dc i2'%0010000000100000' ; frame bits : alert, vis
  220.                     dc i4'0'            ; no title bar, no title...
  221.                     dc i4'0'            ; ref con 0
  222.                     dc i2'0,0,0,0'      ; zoomed rect
  223.                     dc i4'0'            ; color table = default
  224.                     dc i2'0,0'          ; scroll bar XY origin
  225.                     dc i2'0,0'          ; no scroll no max...
  226.                     dc i2'0,0'          ; No zooming...
  227.                     dc i2'0,0'          ; no scrolling
  228.                     dc i2'0,0'          ; no paging....
  229.                     dc i4'0'            ; no info bar, no ref con
  230.                     dc i2'0'            ; info bar height ( none...)
  231.                     dc i4'0'            ; Frame defproc, NIL=standard
  232.                     dc i4'0'            ; no info bar def proc
  233.                     dc i4'displayCache' ; update procedure to display cache
  234.                     dc i2'20,20,195,619'                    ; bounds rect...
  235.                     dc i4'$FFFFFFFF'    ; plane= on top...
  236.                     dc i4'0'            ; NIL storage pointer
  237. WindEnd             equ *
  238. ContRect            dc i2'0,0,180,599'  ; content rectangle
  239.  
  240. WindPointer         ds 4
  241.  
  242. ; Constants used thru the program both represent PI*2
  243.  
  244. TwoPi               dc i1'$1D,$72,$33,$DC,$80,$CF,$0F,$C9,$01,$40'
  245. TwoPiFix            dc i2'$487E,$0006'
  246.  
  247. ; Titles for the bottom of the window
  248.  
  249. IntSineTitle        str 'Integer Math Demo: plotting Y=SIN(X)'
  250. SANESineTitle       str 'SANE Demo: plotting Y=SIN(X)'
  251. IntHarmTitle        str 'Integer Math Demo: plotting complex waveform'
  252. SANEHarmTitle       str 'SANE Demo: plotting complex waveform'
  253.                     end
  254.                     
  255.                     EJECT
  256. *******************************************************************************
  257. *
  258. InitApp             start
  259. *
  260. * Description:      This routine creates our window and zeros out the quitflag
  261. *
  262. *
  263. * Inputs:           None
  264. *
  265. * Outputs:          None
  266. *
  267. * External Refs:
  268. *                   Import newPort
  269. *
  270. * Entry Points:     None
  271. *
  272. *******************************************************************************
  273.                     using Globals
  274.  
  275.                     Stz QuitFlag        ; zero out quit flag
  276.  
  277.                     PushLong #0
  278.                     PushLong #MyWindow
  279.                     _NewWindow          ; create a window to graph in
  280.                     PullLong WindPointer
  281.  
  282.                     PushLong WindPointer
  283.                     _SetPort            ; make the new window the current port
  284.  
  285.                     pha
  286.                     pha
  287.                     pea portCacheInfo|-16
  288.                     pea portCacheInfo
  289.                     jsl newPort
  290.                     pla                 ; The result is also stored in portCacheInfo.
  291.                     pla
  292.  
  293.                     rts
  294.                     end
  295.  
  296.                     EJECT
  297. *******************************************************************************
  298. *
  299. CloseApp            start
  300. *
  301. * Description:      This routine will be called at program end to dispose of
  302. *                   the window.
  303. *
  304. *
  305. * Inputs:           None
  306. *
  307. * Outputs:          None
  308. *
  309. * External Refs:
  310. *                   Import killPort
  311. *
  312. * Entry Points:     None
  313. *
  314. *******************************************************************************
  315.                     using Globals
  316.  
  317.                     PushLong WindPointer
  318.                     _CloseWindow
  319.  
  320.                     pea portCacheInfo|-16
  321.                     pea portCacheInfo
  322.                     jsl killPort
  323.  
  324.                     rts
  325.                     end
  326.  
  327.                     EJECT
  328. *******************************************************************************
  329. *
  330. EventLoop           start
  331. *
  332. * Description:      Main loop. Handles events until the user selects quit
  333. *
  334. *
  335. * Inputs:           None
  336. *
  337. * Outputs:          None
  338. *
  339. * External Refs:
  340. *                   Import Ignore
  341. *                   Import MenuSelect
  342. *
  343. * Entry Points:
  344. *
  345. *******************************************************************************
  346.                     using Globals
  347.  
  348.  
  349.                     pha                 ; Push on space for TaskMaster result
  350.                     PushWord #$FFFF     ; GetNextEvent mask
  351.                     PushLong #EventRecord ; Pointer to Event Record
  352.                     _TaskMaster
  353.  
  354.                     pla                 ; Get TaskMaster result
  355.                     beq EventLoop       ; Remove if you want to use null events
  356.                     asl A               ; Turn it into an index
  357.                     tax
  358.                     jsr (TaskTable,x)   ; Call appropriate event handler
  359.  
  360.                     lda QuitFlag        ; Quit selected?
  361.                     beq EventLoop       ; no - keep looping
  362.  
  363.                     rts                 ; yes- leave the program
  364.  
  365.  
  366. TaskTable           dc i2'Ignore'       ; 0 Null
  367.                     dc i2'Ignore'       ; 1 MouseDown
  368.                     dc i2'Ignore'       ; 2 Mouse Up
  369.                     dc i2'Ignore'       ; 3 KeyDown
  370.                     dc i2'Ignore'       ; 4 Undefined
  371.                     dc i2'Ignore'       ; 5 AutoKey
  372.                     dc i2'Ignore'       ; 6 Update
  373.                     dc i2'Ignore'       ; 7 undefined
  374.                     dc i2'Ignore'       ; 8 activate
  375.                     dc i2'Ignore'       ; 9 Switch
  376.                     dc i2'Ignore'       ; 10 desk acc
  377.                     dc i2'Ignore'       ; 11 device driver
  378.                     dc i2'Ignore'       ; 12 ap
  379.                     dc i2'Ignore'       ; 13 ap
  380.                     dc i2'Ignore'       ; 14 ap
  381.                     dc i2'Ignore'       ; 15 ap
  382.                     dc i2'Ignore'       ; TASK 0 indesk
  383.                     dc i2'MenuSelect'   ; TASK 1 in menuBar
  384.                     dc i2'Ignore'       ; TASK 2 in system window
  385.                     dc i2'Ignore'       ; TASK 3 in content
  386.                     dc i2'Ignore'       ; TASK 4 in Drag
  387.                     dc i2'Ignore'       ; TASK 5 in grow
  388.                     dc i2'Ignore'       ; TASK 6 in goaway
  389.                     dc i2'Ignore'       ; TASK 7 in zoom
  390.                     dc i2'Ignore'       ; TASK 8 in info bar
  391.                     dc i2'Ignore'       ; TASK 9 in special menu
  392.                     dc i2'Ignore'       ; TASK 10 in NDA
  393.                     dc i2'Ignore'       ; TASK 11 in frame
  394.                     dc i2'Ignore'       ; TASK 12 in drop           
  395.  
  396.                     end
  397.                     
  398.                     EJECT
  399. *******************************************************************************
  400. *
  401. MenuSelect          start
  402. *
  403. * Description:      This routine is called when taskmaster returns a code
  404. *                   indicating that the user selected one of our menu options.
  405. *                   This routine will call whatever routine is indicated for
  406. *                   each menu action
  407. *
  408. *
  409. * Inputs:           TaskData - menu selected by the user
  410. *
  411. * Outputs:          None
  412. *
  413. * External Refs:
  414. *                   Import Ignore
  415. *                   Import doAbout
  416. *                   Import doQuit
  417. *                   Import IntSineCurve
  418. *                   Import SANESineCurve
  419. *                   Import IntHarmWave
  420. *                   Import SANEHarmWave
  421. *
  422. * Entry Points:
  423. *
  424. *******************************************************************************
  425.                     using Globals
  426.  
  427.                     lda TaskData        ; get the ID of the menu item selected
  428.                     sec                 ; adjust it to be between 0 and 5
  429.                     sbc #256
  430.                     asl a               ; multiply it by 2
  431.                     tax                 ; and use it as an index into our jump
  432.                     jsr (MenuTable,x)   ; table.
  433.  
  434. MSDone              ANOP
  435.                     PushWord #0         ; menu action complete, unhilite the
  436.                     PushWord TaskData+2 ; selected menu to show we are done
  437.                     _HiliteMenu
  438.  
  439.                     rts                 ; and quit
  440.  
  441. MenuTable           dc i2'doAbout'      ; about shell...
  442.                     dc i2'doQuit'       ; quit selected
  443.                     dc i2'IntSineCurve' ; draw integer math sine wave
  444.                     dc i2'SANESineCurve'                    ; draw sane sine wave
  445.                     dc i2'SANEHarmWave'
  446.                     dc i2'IntHarmWave'
  447.                     end
  448.  
  449.                     EJECT
  450. *******************************************************************************
  451. *
  452. doQuit              start
  453. *
  454. * Description:      Sets the quit flag to inform the event loop that the user
  455. *                   wants to stop the program
  456. *
  457. *
  458. * Inputs:           None
  459. *
  460. * Outputs:          None
  461. *
  462. * External Refs:    None
  463. *
  464. * Entry Points:     None
  465. *
  466. *******************************************************************************
  467.                     using Globals
  468.  
  469.                     lda #$FFFF
  470.                     sta QuitFlag
  471.                     rts
  472.                     end
  473.  
  474. *******************************************************************************
  475. *
  476. Ignore              start
  477. *
  478. * Description:      Called when the program gets an event or menu selection that
  479. *                   it does not want to handle
  480. *
  481. *
  482. * Inputs:           None
  483. *
  484. * Outputs:          None
  485. *
  486. * External Refs:    None
  487. *
  488. * Entry Points:     None
  489. *
  490. *******************************************************************************
  491.                     rts
  492.                     end
  493.  
  494.                     EJECT
  495. *******************************************************************************
  496. *
  497. setCachePort        start
  498. *                   Export setViewPort, displayCache
  499.                     using   Globals
  500.  
  501.                     plx                 ;Clone enough of the stack.
  502.                     tsc
  503.                     sta keepStackPtr
  504.                     ldy #10
  505. aa                  lda 10*2-1,s
  506.                     pha
  507.                     dey
  508.                     bne aa
  509.                     phx
  510.  
  511.                     lda portCacheInfo+2 ;Switch to cache port.
  512.                     pha
  513.                     lda portCacheInfo
  514.                     pha
  515.                     _SetPort
  516.  
  517.                     rts
  518.  
  519. setViewPort         entry
  520.                     plx                 ;Set the stack back to before cloning.
  521.                     lda keepStackPtr
  522.                     tcs
  523.                     phx
  524.  
  525.                     lda WindPointer+2
  526.                     pha
  527.                     lda WindPointer
  528.                     pha
  529.                     _SetPort
  530.  
  531.                     rts
  532.  
  533. keepStackPtr        dc i2'0'
  534.  
  535. displayCache        entry
  536.                     pha
  537.                     pha
  538.                     _GetPort
  539.  
  540.                     lda portCacheInfo+2
  541.                     pha
  542.                     lda portCacheInfo
  543.                     pha
  544.                     _SetPort
  545.  
  546.                     pea cacheLocInfo|-16
  547.                     pea cacheLocInfo
  548.                     _GetPortLoc
  549.  
  550.                     pea cachePortRect|-16
  551.                     pea cachePortRect
  552.                     _GetPortRect
  553.  
  554.                     _SetPort
  555.  
  556.                     pea cacheLocInfo|-16
  557.                     pea cacheLocInfo
  558.                     pea cacheBoundsRect|-16
  559.                     pea cacheBoundsRect
  560.                     lda #0
  561.                     pha
  562.                     pha
  563.                     pha
  564.                     _PPToPort
  565.                     rtl
  566.  
  567. cacheLocInfo        ds 8
  568. cacheBoundsRect     ds 8
  569. cachePortRect       ds 8
  570.  
  571.                     END
  572. *
  573. *******************************************************************************
  574.  
  575.  
  576.  
  577. *******************************************************************************
  578. *
  579. IntSineCurve        start
  580. *
  581. * Description:      This routine will calculate a simple Sine curve and display
  582. *                   it graphically on the screen.           
  583. *
  584. *
  585. * Inputs:           None
  586. *
  587. * Outputs:          None
  588. *
  589. * External Refs:    None
  590. *
  591. * Entry Points:     None
  592. *
  593. *******************************************************************************
  594.                     using Globals
  595.  
  596.                     _WaitCursor
  597.  
  598.                     PushLong #ContRect  ; first, start with a clean screen
  599.                     jsr setCachePort    ; by erasing the old screen
  600.                     _EraseRect
  601.                     jsr setViewPort
  602.                     _EraseRect
  603.  
  604.                     PushWord #10        ; label the bottom of the window
  605.                     PushWord #170       ; to show what we are doing
  606.                     jsr setCachePort
  607.                     _MoveTo
  608.                     jsr setViewPort
  609.                     _MoveTo
  610.  
  611.                     PushLong #IntSineTitle
  612.                     jsr setCachePort
  613.                     _DrawString
  614.                     jsr setViewPort
  615.                     _DrawString
  616.  
  617.                     stzL LoopCount      ; zero the counter to start this thing
  618.  
  619.                     PushWord #0         ; start this drawing off
  620.                     PushWord #80
  621.                     jsr setCachePort
  622.                     _MoveTo
  623.                     jsr setViewPort
  624.                     _MoveTo
  625.  
  626.  
  627. DIMLoop             ANOP
  628.                     LongResult          ; space for results here for all the
  629.                     LongResult          ; following calculations. by pushing
  630.                     LongResult          ; the space here, we do not need to 
  631.                     LongResult          ; adjust the stack between int math calls
  632.                     LongResult          ; and we save time and space
  633.                     
  634.                     PushLong LoopCount  ; Calc: LoopCount/180
  635.                     PushLong One80      ; 
  636.                     _FixDiv             ; leave result on stack for next calc
  637.                                         
  638.                     PushLong RFixPi     ; Calc (LoopCount/180)*PI
  639.                     _FixMul             ; to convert LoopCount to radians
  640.                     
  641.                     _FracSin            ; take the sine of the counter
  642.                     
  643.                     _Frac2Fix           ; convert it back to fixed #
  644.                     
  645.                     PushLong Eighty     ; multiply it by 80 to scale
  646.                     _FixMul             ; we have our number!
  647.                     PullLong YCord      ; and its the y coordinate
  648.  
  649.                     PushWord LoopCount+2 ; X coordinate (HiWord of Fixed)
  650.                     lda YCord+2         ; Y coordinate + 80
  651.                     clc                 ; to scale the number between
  652.                     adc #80             ; 0 and 160
  653.                     pha
  654.                     jsr setCachePort
  655.                     _LineTo             ; draw the linesegment for this point
  656.                     jsr setViewPort
  657.                     _LineTo
  658.  
  659.                     inc LoopCount+2     ; bump the loopcounter
  660.                     lda LoopCount+2     ; and see if we have reached 360
  661.                     cmp #360            ; for a full SINE curve
  662.                     bge DIMDone         ; if so, then finish the loop
  663.                     brl DIMLoop         ; if not do the next iteration
  664.  
  665. DIMDone             _InitCursor
  666.                     rts                 ; finish the routine
  667.  
  668. LoopCount           ds 4                ; Fixed number to store degrees
  669. One80               dc i2'0,180'        ; a fixed number representing 180
  670. Eighty              dc i2'0,80'         ; a FIxed number represenging 80
  671. YCord               ds 4                ; temp storage for the y coordinate
  672. RFixPi              dc i4'$0003243F'    ; 3.14159 (PI in fixed format)
  673.                     end
  674.  
  675.                     EJECT
  676. *******************************************************************************
  677. *
  678. SANESineCurve       start
  679. *
  680. * Description:      This routine will use the SANE toolset to calculate
  681. *                   a Sine curve. It will then plot the points on the screen.
  682. *
  683. *
  684. * Inputs:           None
  685. *
  686. * Outputs:          None
  687. *
  688. * External Refs:    None
  689. *
  690. * Entry Points:     None
  691. *
  692. *******************************************************************************
  693.                     using Globals
  694.  
  695.                     _WaitCursor
  696.  
  697.                     PushLong #ContRect  ; first, start with a clean screen
  698.                     jsr setCachePort    ; by erasing the old screen
  699.                     _EraseRect
  700.                     jsr setViewPort
  701.                     _EraseRect
  702.  
  703.                     PushWord #10        ; label the bottom of the window
  704.                     PushWord #170       ; to show what we are doing
  705.                     jsr setCachePort
  706.                     _MoveTo
  707.                     jsr setViewPort
  708.                     _MoveTo
  709.  
  710.                     PushLong #SANESineTitle
  711.                     jsr setCachePort
  712.                     _DrawString
  713.                     jsr setViewPort
  714.                     _DrawString
  715.                     
  716.                     PushWord #0         ; start this drawing off
  717.                     PushWord #80        ; in the middle of the screen
  718.                     jsr setCachePort
  719.                     _MoveTo
  720.                     jsr setViewPort
  721.                     _MoveTo
  722.                     
  723.                     stz LoopCount
  724.  
  725. DSaneLoop           ANOP
  726.                     ExtendEq SanePi,TempResult ; move pi/180 into the result
  727.  
  728.                     PushLong #LoopCount ; convert LoopCount to Radians
  729.                     PushLong #TempResult
  730.                     FMULI               ; by multiplying by pi/180
  731.  
  732.                     PushLong #TempResult
  733.                     FSINX               ; now get the SINE of it
  734.  
  735.                     PushLong #Eighty    ; multiply by 80
  736.                     PushLong #TempResult
  737.                     FMULI
  738.  
  739.                     PushLong #TempResult
  740.                     PushLong #YCord     ; convert to an Integer
  741.                     FX2I
  742.  
  743.                     PushWord LoopCount  ; X coordinate
  744.                     lda YCord           ; Y coordinate + 80
  745.                     clc                 ; to get a number between 
  746.                     adc #80             ; 0 and 160
  747.                     pha
  748.                     jsr setCachePort    ; draw the line segement
  749.                     _LineTo
  750.                     jsr setViewPort
  751.                     _LineTo
  752.  
  753.                     inc LoopCount       ; bump the counter
  754.                     lda LoopCount
  755.                     cmp #360            ; and see if we have done all 360 degrees
  756.                     bge DSaneDone       ; if so then end
  757.                     brl DSaneLoop       ; if not, get next value
  758.  
  759. DSaneDone           _InitCursor
  760.                     rts
  761.  
  762. LoopCount           ds 4
  763. SanePi              dc i1'$AE,$C8,$E9,$94,$12,$35,$FA,$8E,$F9,$3F' ; pi/180 ...
  764. TempResult          ds 10
  765. Eighty              dc i4'80'
  766. YCord               ds 4
  767.                     end
  768.  
  769.  
  770.                     EJECT
  771. *******************************************************************************
  772. *
  773. FFTransData         data
  774. *
  775. * Description:      Data used by both FFT calculation routines
  776. *
  777. *
  778. * Inputs:           None
  779. *
  780. * Outputs:          None
  781. *
  782. * External Refs:    None
  783. *
  784. * Entry Points:     None
  785. *
  786. *******************************************************************************
  787.  
  788. FixCount            dc i2'0'            ; fractional portsion of our
  789. Count               ds 2                ; fixed point counter
  790. LoopCount           ds 2
  791. FixSamp             dc i2'0'            ; fractional portion of the sample var
  792. Sample              ds 2                ; sample to figure for
  793. FixMaxSamp          dc i2'0'            ; fractional portion of Max Sample
  794. MaxSample           dc i2'256'          ; maximum number of samples
  795. MaxHarm             dc i2'6'            ; maximum number of harmonics
  796. MaxValue            ds 10               ; maximum vaule of the FFT
  797. AmpTbl              dc i2'0,10,8,6,4,2,1'                   ; amplitudes of each harmonic
  798. PhaseTbl            dc i2'0,1,2,4,6,8,10'                   ; high word of each fixed phase
  799. PhaseTblF           dc i4'0,6554,13107,26214,39321,52428,$FFFF'
  800. TempValue           ds 10               ; intermediate result storage
  801. TempFactor          ds 10
  802. Temp1               ds 10
  803. Temp2               ds 10
  804. FFTWave             ds 2560             ; table to hold intermediate values
  805. MyDecForm           dc i2'1'
  806.                     dc i2'8'            ; 8 digits after the decimal place
  807. TempI               ds 2
  808. TempF               ds 4
  809. Const127            dc i2'79'
  810. Const80Fix          dc i4'$004F000'
  811. Const10             dc i2'10'
  812.                     end
  813.  
  814.  
  815.                     EJECT
  816. *******************************************************************************
  817. *
  818. SANEHarmWave        start
  819. *
  820. * Description:      Create a complex harmonic wave using SANE
  821. *
  822. *
  823. * Inputs:           None
  824. *
  825. * Outputs:          None
  826. *
  827. * External Refs:
  828. *                   Import SaneFFTIteration
  829. *                   Import doNormIter
  830. *
  831. * Entry Points:
  832. *
  833. *******************************************************************************
  834.  
  835.                     using Globals
  836.                     using FFTransData
  837.  
  838.                     _WaitCursor
  839.  
  840.                     PushLong #ContRect  ; first, start with a clean screen
  841.                     jsr setCachePort    ; by erasing the old screen
  842.                     _EraseRect
  843.                     jsr setViewPort
  844.                     _EraseRect
  845.  
  846.                     PushWord #10        ; label the bottom of the window
  847.                     PushWord #170       ; to show what we are doing
  848.                     jsr setCachePort
  849.                     _MoveTo
  850.                     jsr setViewPort
  851.                     _MoveTo
  852.                     
  853.                     PushLong #SANEHarmTitle
  854.                     jsr setCachePort
  855.                     _DrawString
  856.                     jsr setViewPort
  857.                     _DrawString
  858.                     
  859.  
  860.                     PushWord #0         ; start this drawing off
  861.                     PushWord #80        ; at the left edge
  862.                     jsr setCachePort
  863.                     _MoveTo
  864.                     jsr setViewPort
  865.                     _MoveTo
  866.  
  867.                     stz Sample          ; and zero out all global values
  868.                     STZEXT MaxValue
  869.                     STZEXT Temp1
  870.                     STZEXT Temp2
  871.                     STZEXT TempFactor
  872.  
  873. DHWLoop1            jsr SaneFFTIteration ; do one iteration
  874.  
  875.                     lda Sample          ; now save tempValue into our array
  876.                     asl a               ; multiply by 2
  877.                     sta Temp1           ; and save it for a sec
  878.                     asl a
  879.                     asl a               ; multiply by 8
  880.                     clc
  881.                     adc Temp1           ; x*8+x*2=x*10
  882.                     tax                 ; use as an index into the sample array
  883.  
  884.                     lda TempValue       ; now stow the current value
  885.                     sta FFTWave,x       ; into our wave table. Later this
  886.                     lda TempValue+2     ; table will be normalized
  887.                     sta FFTWave+2,x
  888.                     lda TempValue+4
  889.                     sta FFTWave+4,x
  890.                     lda TempValue+6
  891.                     sta FFTWave+6,x
  892.                     lda TempValue+8
  893.                     sta FFTWave+8,x
  894.  
  895.                     inc Sample          ; bump the sample counter
  896.                     lda #255
  897.                     cmp Sample          ; test to see if we have reached the 
  898.                     bge DHWLoop1        ; last sample, if not do the next one
  899.  
  900. ; if the last sample was reached, it is time to go thru the wavetable and
  901. ; convert all the number so they are between 0 and 160.
  902.                     
  903.                     stz Count           ; initialize the index
  904. DHWLoop2            inc Count
  905.                     jsr doNormIter      ; normalize one iteration
  906.  
  907.                     PushWord Count      ; X coordinate
  908.                     PushWord TempValue  ; value returned by doNormIter
  909.                     jsr setCachePort    ; draw the line
  910.                     _LineTo
  911.                     jsr setViewPort
  912.                     _LineTo
  913.  
  914.                     lda #255            ; see if the counter has reached the max
  915.                     cmp Count           ; sample we recorded
  916.                     bge DHWLoop2        ; if not, do another point
  917.  
  918.  
  919.                     _InitCursor         ; if it has, then we can simply end
  920.                     rts
  921.                     end
  922.                     
  923.                     EJECT
  924. *******************************************************************************
  925. *
  926. SaneFFTIteration    start
  927. *
  928. * Description:      This routine takes the current sample value and computes
  929. *                   all the harmonic components that make up the wave for that
  930. *                   sample.
  931. *
  932. *
  933. * Inputs:           Sample - current sample to compute for
  934. *
  935. * Outputs:          TempValue - output sample value
  936. *
  937. * External Refs:
  938. *
  939. * Entry Points:
  940. *
  941. *******************************************************************************
  942.                     using Globals
  943.                     using FFTransData
  944.  
  945.                     STZEXT TempValue
  946.  
  947.                     PushLong #Sample
  948.                     PushLong #TempFactor
  949.                     FI2X                ; convert the max sample rate to extended
  950.  
  951.                     PushLong #MaxSample
  952.                     PushLong #Temp1
  953.                     FI2X
  954.  
  955.                     PushLong #Temp1
  956.                     PushLong #TempFactor
  957.                     FDIVX               ; TempFactor:=TempFactor/Temp1
  958.  
  959.                     PushLong #TwoPi
  960.                     PushLong #TempFactor
  961.                     FMULX               ; TempFactor:=6.28318*(count/maxSample)
  962.  
  963.                     stz Count           ; zero out the counter
  964.  
  965. FFLoop              ANOP
  966.                     ExtendEq TwoPi,Temp2
  967.  
  968.                     lda Count           ; get the count
  969.                     asl a               ; multiply by 2
  970.                     tax
  971.                     lda PhaseTbl,x
  972.                     sta TempI
  973.                     PushLong #TempI
  974.                     PushLong #Temp1
  975.                     FI2X                ; Temp1:=Phase[count]
  976.  
  977.                     PushLong #Const10
  978.                     PushLong #Temp1
  979.                     FDIVI               ; divide by 10 to make it fractional
  980.  
  981.                     PushLong #Temp1
  982.                     PushLong #Temp2
  983.                     FMulX               ; Temp2:=(Temp1)/10*TwoPi
  984.  
  985.                     ExtendEq TempFactor,Temp1
  986.  
  987.                     PushLong #Count
  988.                     PushLong #Temp1
  989.                     FMULI               ; tempi:=count*TempFactor
  990.  
  991.                     PushLong #Temp2
  992.                     PushLong #Temp1
  993.                     FADDX               ; Temp1:=((count*TempFactor)+(6.28318*Phase[count]))
  994.  
  995.                     PushLong #Temp1
  996.                     FCOSX               ; Temp1:=Cos(Temp1)
  997.  
  998.                     lda Count           ; get the count
  999.                     asl a               ; multiply by 2
  1000.                     tax
  1001.                     lda AmpTbl,x
  1002.                     sta TempI
  1003.                     PushLong #TempI
  1004.                     PushLong #Temp1
  1005.                     FMULI               ; Temp1:=Temp1*Amp[count]
  1006.  
  1007.                     PushLong #Temp1
  1008.                     PushLong #TempValue
  1009.                     FADDX               ; finally tempValue:=tempValue+Temp1
  1010.  
  1011.                     PushLong #TempValue
  1012.                     PushLong #Temp1
  1013.                     FX2X                ; copy tempvalue into Temp1
  1014.  
  1015.                     PushLong #Temp1
  1016.                     FABSX
  1017.  
  1018.                     PushLong #Temp1
  1019.                     PushLong #MaxValue
  1020.                     FCMPX               ; now update the max value if needed
  1021.  
  1022.                     FBLE FFTL010        ; if the new number <= old max ignore next line
  1023.  
  1024.                     ExtendEq Temp1,MaxValue
  1025.  
  1026. FFTL010             ANOP
  1027.                     inc Count
  1028.                     lda Count
  1029.                     cmp MaxHarm         ; are we done yet???
  1030.                     bge FFTDone
  1031.                     brl FFLoop
  1032. FFTDone             rts
  1033.                     end
  1034.  
  1035.                     EJECT
  1036. *******************************************************************************
  1037. *
  1038. doNormIter          start
  1039. *
  1040. * Description:      Normalize one iteration of the wavetable. This routine
  1041. *                   takes the current sample value and converts it to 
  1042. *
  1043. *
  1044. * Inputs:           Count - current sample number
  1045. *
  1046. * Outputs:          TempValue - the normalized value
  1047. *
  1048. * External Refs:    None
  1049. *
  1050. * Entry Points:     None
  1051. *
  1052. *******************************************************************************
  1053.                     using Globals
  1054.                     using FFTransData
  1055.  
  1056.                     lda Count
  1057.                     asl a               ; multiply by 2
  1058.                     sta Temp1           ; and save it for a sec
  1059.                     asl a
  1060.                     asl a               ; multiply by 8
  1061.                     clc
  1062.                     adc Temp1           ; x*8+x*2=x*10
  1063.                     tax
  1064.  
  1065.                     lda FFTWave,x       ; now load the current value
  1066.                     sta TempValue
  1067.                     lda FFTWave+2,x
  1068.                     sta TempValue+2
  1069.                     lda FFTWave+4,x
  1070.                     sta TempValue+4
  1071.                     lda FFTWave+6,x
  1072.                     sta TempValue+6
  1073.                     lda FFTWave+8,x
  1074.                     sta TempValue+8
  1075.  
  1076.                     ExtendEq MaxValue,Temp2
  1077.  
  1078.                     PushLong #Temp2
  1079.                     PushLong #TempValue ; divide the two
  1080.                     FDIVX
  1081.  
  1082.                     PushLong #Const127  ; now scale it
  1083.                     PushLong #TempValue
  1084.                     FMULI
  1085.  
  1086.                     PushLong #Const127
  1087.                     PushLong #TempValue
  1088.                     FADDI
  1089.  
  1090.                     PushLong #TempValue ; now, convert ot to an integer
  1091.                     PushLong #TempI
  1092.                     FX2I
  1093.  
  1094.                     lda TempI
  1095.                     sta TempValue
  1096.                     rts
  1097.                     end
  1098.  
  1099.  
  1100.  
  1101.                     EJECT
  1102. *******************************************************************************
  1103. *
  1104. IntHarmWave         start
  1105. *
  1106. * Description:      This routine will create a complex waveformusing the 
  1107. *                   integer math tools
  1108. *
  1109. *
  1110. * Inputs:           None
  1111. *
  1112. * Outputs:          None
  1113. *
  1114. * External Refs:
  1115. *                   Import IntFFTIteration
  1116. *                   Import IntHarmI
  1117. *
  1118. * Entry Points:
  1119. *
  1120. *******************************************************************************
  1121.                     using Globals
  1122.                     using FFTransData
  1123.  
  1124.                     _WaitCursor
  1125.  
  1126.                     PushLong #ContRect  ; first, start with a clean screen
  1127.                     jsr setCachePort    ; by erasing the old screen
  1128.                     _EraseRect
  1129.                     jsr setViewPort
  1130.                     _EraseRect
  1131.  
  1132.                     PushWord #10        ; label the bottom of the window
  1133.                     PushWord #170       ; to show what we are doing
  1134.                     jsr setCachePort
  1135.                     _MoveTo
  1136.                     jsr setViewPort
  1137.                     _MoveTo
  1138.                     
  1139.                     PushLong #IntHarmTitle
  1140.                     jsr setCachePort
  1141.                     _DrawString
  1142.                     jsr setViewPort
  1143.                     _DrawString
  1144.                     
  1145.                     PushWord #0         ; start this drawing off
  1146.                     PushWord #80
  1147.                     jsr setCachePort
  1148.                     _MoveTo
  1149.                     jsr setViewPort
  1150.                     _MoveTo
  1151.  
  1152.                     stz Sample          ; zero out some starting values
  1153.                     STZL MaxValue
  1154.                     STZL Temp1
  1155.                     STZL Temp2
  1156.                     STZL TempFactor
  1157.  
  1158.  
  1159. DIWLoop1            jsr IntFFTIteration ; do one iteration of the wave
  1160.  
  1161.                     lda Sample          ; now save tempValue into our array
  1162.                     asl a               ; multiply by 2
  1163.                     asl a
  1164.                     tax
  1165.  
  1166.                     lda TempValue       ; now stow the temp value
  1167.                     sta FFTWave,x       ; into an array for later use
  1168.                     lda TempValue+2
  1169.                     sta FFTWave+2,x
  1170.  
  1171.                     inc Sample          ; bump the sample counter
  1172.                     lda #255            
  1173.                     cmp Sample          ; see if we are done
  1174.                     bge DIWLoop1        ; if not, get another sample
  1175.  
  1176. ; Now that the array of values has been created. Go thru and scale
  1177. ; each value so that it fits in our wave and is between 0 and 160
  1178.  
  1179.                     stz Count           ; zero the sample counter
  1180. DIWLoop2            inc Count
  1181.                     jsr IntHarmI        ; normalize one iteration
  1182.  
  1183.                     PushWord Count      ; X coordinate
  1184.                     PushWord TempValue
  1185.                     jsr setCachePort    ; draw the line
  1186.                     _LineTo
  1187.                     jsr setViewPort
  1188.                     _LineTo
  1189.  
  1190.                     lda #255
  1191.                     cmp Count
  1192.                     bge DIWLoop2
  1193.  
  1194.                     _InitCursor
  1195.                     rts
  1196.                     end
  1197.  
  1198.                     EJECT
  1199. *******************************************************************************
  1200. *
  1201. IntFFTIteration     start
  1202. *
  1203. * Description:      This routine will calculate one single iteration of the 
  1204. *                   wave. It will add a the Cosine*amp of each desired
  1205. *                   harmonic to create a single sample
  1206. *
  1207. *
  1208. * Inputs:           None
  1209. *
  1210. * Outputs:          None
  1211. *
  1212. * External Refs:
  1213. *
  1214. * Entry Points:
  1215. *
  1216. *******************************************************************************
  1217.                     using Globals
  1218.                     using FFTransData
  1219.  
  1220.                     stzL TempValue
  1221.  
  1222.                     LongResult           ; push room on the stack
  1223.                     LongResult           ; push room on the stack
  1224.                     PushLong FixSamp    ; sample fixed number format
  1225.                     PushLong FixMaxSamp ; max sample fixed point number
  1226.                     _FixDiv
  1227.  
  1228.                     PushLong TwoPiFix
  1229.                     _FixMul             ; now multiply the two to get theFactor
  1230.                     PullLong TempFactor
  1231.  
  1232.  
  1233.                     stz Count           ; zero out the counter
  1234.  
  1235. FFLoop              ANOP
  1236.  
  1237.                     lda Count           ; get the count
  1238.                     asl a               ; multiply by 2
  1239.                     asl a
  1240.                     tax
  1241.                     lda PhaseTblF,x
  1242.                     sta TempF
  1243.                     lda PhaseTblF+2,X
  1244.                     sta TempF+2
  1245.  
  1246.                     LongResult           ; push room on the stack
  1247.                     PushLong TwoPiFix
  1248.                     PushLong TempF
  1249.                     _FixMul             ; Temp2:=Phase(Count)*TwoPi
  1250.                     PullLong Temp2
  1251.  
  1252.                     LongResult           ; push room on the stack
  1253.                     PushLong FixCount
  1254.                     PushLong TempFactor
  1255.                     _FixMul             ; Temp1:=count*TempFactor
  1256.                     PullLong Temp1
  1257.  
  1258.                     lda Temp1           ; Temp2:=Temp1+Temp2
  1259.                     clc
  1260.                     adc Temp2
  1261.                     sta Temp2
  1262.                     lda Temp1+2
  1263.                     adc Temp2+2
  1264.                     sta Temp2+2
  1265.  
  1266.                     LongResult           ; push room on the stack
  1267.                     LongResult           ; push room on the stack
  1268.                     LongResult           ; push room on the stack
  1269.                     PushLong Temp2
  1270.                     _FracCos            ; Temp2:=Cos(Temp2)
  1271.                     _Frac2Fix           ; convert back to fixed!
  1272.                     PullLong Temp2
  1273.  
  1274.                     PushLong Temp2
  1275.                     lda Count           ; get the count
  1276.                     asl a               ; multiply by 2
  1277.                     tax
  1278.                     lda AmpTbl,x
  1279.                     pha
  1280.                     pea $0              ; Low word of fixed count
  1281.                     _FixMul             ; Temp1:=Temp1*Amp[count]
  1282.                     PullLong Temp2
  1283.  
  1284.                     lda TempValue       ; now add it to tempValue
  1285.                     clc
  1286.                     adc Temp2
  1287.                     sta TempValue
  1288.                     sta Temp2
  1289.                     lda TempValue+2
  1290.                     adc Temp2+2
  1291.                     sta TempValue+2     ; Now test for max value
  1292.                     sta Temp2+2
  1293.                     bpl TestHigh        ; number is positive, test for high
  1294.                     lda #0              ; Negate this number to get absolute value
  1295.                     sec
  1296.                     sbc Temp2           ; negate this number
  1297.                     sta Temp2
  1298.                     lda #0
  1299.                     sbc Temp2+2
  1300.                     sta Temp2+2
  1301. TestHigh            lda Temp2+2
  1302.                     cmp MaxValue+2      ; is it bigger than max value+2?
  1303.                     beq FFTTestLow      ; if equal test the low byte
  1304.                     bge FFTStoreMax     ; if greater move it to high
  1305.                     bra FFTL010
  1306. FFTTestLow          lda Temp2
  1307.                     cmp MaxValue        ; is it bigger?
  1308.                     blt FFTL010
  1309. FFTStoreMax         lda Temp2+2
  1310.                     sta MaxValue+2
  1311.                     lda Temp2
  1312.                     sta MaxValue
  1313.  
  1314. FFTL010             ANOP
  1315.                     inc Count
  1316.                     lda Count
  1317.                     cmp MaxHarm         ; are we done yet???
  1318.                     bge FFTDone
  1319.                     brl FFLoop
  1320. FFTDone             rts
  1321.                     end
  1322.  
  1323.                     EJECT
  1324. *******************************************************************************
  1325. *
  1326. IntHarmI            start
  1327. *
  1328. * Description:      Takes an iteration of the wave divides it by the max value
  1329. *                   and multiplies it by 160 to create a valid screen location
  1330. *
  1331. *
  1332. * Inputs:           None
  1333. *
  1334. * Outputs:          None
  1335. *
  1336. * External Refs:
  1337. *
  1338. * Entry Points:
  1339. *
  1340. *******************************************************************************
  1341.                     using Globals
  1342.                     using FFTransData
  1343.  
  1344.                     lda Count
  1345.                     asl a               ; multiply by 4
  1346.                     asl a
  1347.                     tax
  1348.                     lda FFTWave+2,x     ; push current value on stack
  1349.                     sta Temp1+2
  1350.                     lda FFTWave,x       ; 
  1351.                     sta Temp1
  1352.  
  1353.                     LongResult           ; push room on the stack
  1354.                     LongResult           ; push room on the stack
  1355.                     PushLong Temp1
  1356.                     PushLong MaxValue   ; divide it by maxvalue
  1357.                     _FixDiv
  1358.                     PullLong Temp2
  1359.  
  1360.                     PushLong Temp2
  1361.                     PushWord #$4F
  1362.                     PushWord #0         ; now scale it
  1363.                     _FixMul
  1364.                     PullLong Temp1
  1365.  
  1366.                     lda Temp1+2
  1367.                     clc
  1368.                     adc #79
  1369.                     sta TempValue
  1370.                     rts
  1371.                     end
  1372.  
  1373.                     copy math.init.asm
  1374.  
  1375.                     END
  1376.